/**
 * @file swei_blinddata.c
 * @brief 
 * @author  ()
 * @version 1.0
 * @date 2024-09-19
 * 
 * @copyright Copyright (C) 2019 Queclink Wireless Solutions (ShenZhen) Co., Ltd. All Rights Reserved.
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2024-09-19 <td>1.0     <td>     <td>内容
 * </table>
 */
#include "include/port/swei_log.h"

#include "include/swei_blinddata.h"
#include "include/swei_cache.h"
#include "global.h"
#include "FreeRTOS.h"
#include "include/swei_cache.h"
#include "flash/flash_main.h"
#include "aadl/include/aadl/flash.h"

int32_t cache2flash(swei_datatype_t *dat, uint8_t *flash_data_ptr);

/**
 * @brief cache数据存入blinddata
 * @param  dat              My Param doc
 */
void swei_cache2blinddata(swei_datatype_t *dat)
{
    uint8_t *flash_data = NULL;
    uint32_t flash_len = 0;

    if(NULL == dat)
    {
        log_e("dat param error\r\n");
        return;
    }
    
    // 2. 分配空间
    flash_data = qlmalloc(sizeof(swei_datatype_t) + dat->data_len - 4);
    if(NULL == flash_data)
    {
        log_e("qlmalloc memory failed!\r\n");
        return;
    }

    // 3. 数据结构转顺序存储类型
    flash_len = cache2flash(dat, flash_data);
    if(flash_len)
    {
        // 数据存入flash并推出cache队列
        swei_blinddata_push(flash_data, flash_len);
        swei_cache_pop(dat, true);
    }
    
    // 4. 释放空间
    qlfree(flash_data);
    flash_data = NULL;
    if(dat->data_ptr)
    {
        qlfree(dat->data_ptr);
    }
}

/**
 * @brief cache转flash顺序结构
 * @param  flash_data       My Param doc
 * @param  dat              My Param doc
 * @return int32_t  数据有效长度
 */
int32_t cache2flash(swei_datatype_t *dat, uint8_t *flash_data_ptr)
{
    if(!dat || !flash_data_ptr)
        return 0;
    
    dat->vaild = 0xDEADBEEF;
    memcpy(flash_data_ptr, dat, sizeof(swei_datatype_t) - 4);
    memcpy(flash_data_ptr + sizeof(swei_datatype_t) - 4,
                     dat->data_ptr, dat->data_len);

    return sizeof(swei_datatype_t) + dat->data_len - 4;
}

/**
 * @brief 数据存入flash
 * @param  flash_data_ptr   My Param doc
 * @param  flash_data_len   存入flash长度
 */
void swei_blinddata_push(uint8_t *flash_data_ptr, uint32_t flash_data_len)
{
    aad_flash_circular_write(QUEUE_RECORD_ID, flash_data_ptr, flash_data_len, 0, 0);
}

/**
 * @brief 数据转出flash
 * @param  flash_data_ptr   My Param doc
 * @return int32_t 
 */
int32_t swei_blinddata_peek(uint8_t *flash_data_ptr, uint16_t max_flash_len)
{
    if(NULL == flash_data_ptr)
        return 0;
    
    return aad_flash_circular_peek(QUEUE_RECORD_ID, flash_data_ptr, max_flash_len);
}

/**
 * @brief 数据转出flash
 * @param  flash_data_ptr   My Param doc
 * @return int32_t 
 */
int32_t swei_blinddata_pop(uint8_t *flash_data_ptr, uint16_t max_flash_len)
{
    if(NULL == flash_data_ptr)
        return 0;

    return aad_flash_circular_read(QUEUE_RECORD_ID, flash_data_ptr, max_flash_len);
}

/**
 * @brief 获取flash中有效的报文个数
 * @return int32_t 
 */
int32_t swei_blinddata_item_get(void)
{
    return aad_flash_circular_count_get(QUEUE_RECORD_ID);
}

/**
 * @brief 清空flash盲区数据
 * @param  void
 * @return int32_t 
 */
int32_t swei_blinddata_clear(void)
{
    return aad_flash_zone_clear(QUEUE_RECORD_ID, AADL_WAIT | AADL_KEEP_OUTSIDE , 0);
}

